{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7e2c4bbb-5e8b-4d84-9997-ecb2c349cf54",
   "metadata": {},
   "source": [
    "## First step - generate training data from examples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "id": "16cf3aa2-f407-4b95-8b9e-c3c586f67835",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "import pandas as pd\n",
    "from datetime import datetime, timedelta,timezone\n",
    "from datasets import load_dataset, Dataset\n",
    "from dotenv import load_dotenv\n",
    "import os\n",
    "from openai import OpenAI\n",
    "import json\n",
    "import tiktoken\n",
    "from IPython.display import display, Markdown\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "id": "375302b6-b6a7-46ea-a74c-c2400dbd8bbe",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load environment variables in a file called .env\n",
    "load_dotenv()\n",
    "\n",
    "# Replace with your CoinAPI key\n",
    "API_KEY = os.getenv('YOUR_COINAPI_KEY')\n",
    "\n",
    "# Define the base URL for CoinAPI\n",
    "BASE_URL = 'https://rest.coinapi.io/v1/ohlcv/'\n",
    "OLLAMA_URL = \"http://localhost:11434/v1\"\n",
    "\n",
    "os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY', 'your-key-if-not-using-env')\n",
    "# URL to fetch the OHLCV data\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "id": "d0cc964d",
   "metadata": {},
   "outputs": [],
   "source": [
    "openai = OpenAI()\n",
    "\n",
    "ollama = OpenAI(\n",
    "    base_url=OLLAMA_URL,\n",
    "    api_key='OLAMMA'\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "id": "8a0c9fff-9eff-42fd-971b-403c99d9b726",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define the symbol and timeframe\n",
    "base_data = {\n",
    "    'name': 'Cardano',\n",
    "    'symbol': f'BINANCE_SPOT_ADA_USDT',\n",
    "    'timeframe': '1DAY',\n",
    "    'time_range': 365 * 2\n",
    "}\n",
    "\n",
    "\n",
    "# Calculate the start date for one year ago\n",
    "end_date = datetime.now(tz=timezone.utc)\n",
    "\n",
    "start_date = end_date - timedelta(days=base_data['time_range'])\n",
    "\n",
    "# Format the dates in the required format (ISO 8601)\n",
    "start_date_str = start_date.strftime('%Y-%m-%dT%H:%M:%S')\n",
    "end_date_str = end_date.strftime('%Y-%m-%dT%H:%M:%S')\n",
    "\n",
    "# Headers for authentication\n",
    "headers = {\n",
    "    'X-CoinAPI-Key': API_KEY\n",
    "}\n",
    "\n",
    "# URL to fetch the OHLCV base_data\n",
    "url = f'{BASE_URL}{base_data['symbol']}/history'\n",
    "\n",
    "# Request parameters\n",
    "params = {\n",
    "    'period_id': base_data['timeframe'],\n",
    "    'time_start': start_date_str,\n",
    "    'time_end': end_date_str,\n",
    "    'limit': 1000  # Maximum number of records per request\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "id": "586b07ba-5396-4c34-a696-01c8bc3597a0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "729"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Fetch the data\n",
    "response = requests.get(url, headers=headers, params=params)     \n",
    "len(response.json())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "id": "953422d0-2e75-4d01-862e-6383df54d9e5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      Timestamp    Open    High     Low   Close\n",
      "724  2025-02-06  0.7325  0.7660  0.6978  0.7052\n",
      "725  2025-02-07  0.7052  0.7532  0.6902  0.7072\n",
      "726  2025-02-08  0.7072  0.7180  0.6815  0.7005\n",
      "727  2025-02-09  0.7006  0.7160  0.6503  0.6814\n",
      "728  2025-02-10  0.6815  0.7177  0.6632  0.7037\n"
     ]
    }
   ],
   "source": [
    "# Check for successful response\n",
    "if response.status_code == 200:\n",
    "    data = response.json()\n",
    "\n",
    "    if data:\n",
    "        # Convert to DataFrame for better readability\n",
    "        df = pd.DataFrame(data)\n",
    "\n",
    "        df = df[[\"time_period_start\", \"price_open\", \"price_high\", \"price_low\", \"price_close\"]]\n",
    "        df.columns = [\"Timestamp\", \"Open\", \"High\", \"Low\", \"Close\"]\n",
    "\n",
    "        # Convert timestamp to readable format\n",
    "        df[\"Timestamp\"] = pd.to_datetime(df[\"Timestamp\"]).dt.strftime(\"%Y-%m-%d\")\n",
    "\n",
    "        # Display the first few rows of the data\n",
    "        print(df.tail())\n",
    "        \n",
    "        # Convert last 365 days of data into JSON format\n",
    "        price_history = df.to_dict(orient=\"records\")\n",
    "       \n",
    "    else:\n",
    "        print('No data found for the given period.')\n",
    "else:\n",
    "    print(f'Error fetching data: {response.status_code}, {response.text}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "ada5ed4f",
   "metadata": {},
   "outputs": [],
   "source": [
    "def count_tokens(text, model=\"gpt-4o\"):\n",
    "    encoding = tiktoken.encoding_for_model(model)\n",
    "    return len(encoding.encode(text))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab47d974",
   "metadata": {},
   "outputs": [],
   "source": [
    "  # Construct prompt \n",
    "\n",
    "prompt = f\"\"\"\n",
    "  Given the last 365 days of ${base_data['name']} OHLC data:\n",
    "\n",
    "  {json.dumps(price_history, indent=2)}\n",
    "\n",
    "  Analyze this data and provide a trading signal (Buy, Sell, or Hold) for today based on the trend and the price action.\n",
    "  Note that today is {end_date.strftime('%Y-%m-%d')}\n",
    "  Also, provide short term ,mid term and long term signals.\n",
    "  \"\"\"\n",
    "num_tokens = count_tokens(prompt)\n",
    "print(f\"Estimated Tokens: {num_tokens}\")\n",
    "\n",
    "print(prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b40fec12",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "To analyze this data, I'll use a combination of moving averages, relative strength index (RSI), and other technical indicators. Please note that this is a simplified analysis and should not be considered as professional trading advice.\n",
       "\n",
       "**Current Data**\n",
       "\n",
       "For 2025-02-10, the opening price is not available. However, we can calculate the current prices based on the historical data provided.\n",
       "\n",
       "Let's assume the last known close price for 2025-02-09 was $0.6815. For simplicity, let's use this as the opening price for today (2025-02-10).\n",
       "\n",
       "**Short-Term Signal**\n",
       "\n",
       "For a short-term signal, I'll use a simple moving average crossover system.\n",
       "\n",
       "* Short-Term Moving Average (20 days): $0.6922\n",
       "* Short-Term Moving Average (10 days): $0.6747\n",
       "\n",
       "Since the 20-day MA ($0.6922) is above the 10-day MA ($0.6747), we can conclude that **Buy** in this timeframe.\n",
       "\n",
       "**Mid-Term Signal**\n",
       "\n",
       "For a mid-term signal, I'll use RSI.\n",
       "\n",
       "* Current Price: $0.6815\n",
       "* Overbought Region: 70-80\n",
       "* Oversold Region: 20-50\n",
       "\n",
       "The current price ($0.6815) is at the lower end of the oversold region (20-50), indicating a potential buying opportunity.\n",
       "\n",
       "Since RSI values are not provided for the entire dataset, we'll use an RSI value of 30 (midpoint of the low and high values). At $0.6815, RSI is approximately 34.\n",
       "\n",
       "* Mid-Term Moving Average: Not available\n",
       "* Mid-Term Momentum: Rising\n",
       "\n",
       "Considering the oversold region and rising momentum, **Hold** is a reasonable mid-term strategy for today.\n",
       "\n",
       "**Long-Term Signal**\n",
       "\n",
       "For a long-term signal, I'll use the overall trend direction based on historical data.\n",
       "\n",
       "The dataset shows an upward trend (average True Range, AtR, value has been increasing). From 2025-02-03 to 2025-02-09, there were 6 consecutive increases in this dataset. That's a strong positive trend.\n",
       "\n",
       "Since there are no obvious signs of weakness in the long-term data or divergence with other trends (like 50-day MA), I recommend **Hold** for an extended holding period, keeping an eye on RSI values and adjusting positions as needed to stay ahead of potential price drops.\n",
       "\n",
       "**Summary**\n",
       "\n",
       "* Short-Term: **Buy**\n",
       "* Mid-Term: **Hold**\n",
       "* Long-Term: **Hold**"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def get_response(prompt):\n",
    "    new_response = ollama.chat.completions.create(model=\"llama3.2\",\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": f\"You are a trading analyst providing Buy/Sell/Hold signals based on ${base_data['name']} price history.Note that today is {end_date.strftime('%Y-%m-%d')}\"},\n",
    "        {\"role\": \"user\", \"content\": prompt}\n",
    "    ],\n",
    "    stream=True,\n",
    "    max_tokens=5500\n",
    "    )\n",
    "    markdown_content = \"\"\n",
    "    \n",
    "    # Stream response and accumulate markdown content\n",
    "    for chunk in new_response:\n",
    "        content = chunk.choices[0].delta.content or ''\n",
    "        markdown_content += content\n",
    "        \n",
    "        # Clear output and display updated markdown\n",
    "        display(Markdown(markdown_content), clear=True)\n",
    "        \n",
    "        yield content\n",
    "\n",
    "# Call the function and consume the generator to start streaming\n",
    "for _ in get_response(prompt):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "id": "ba09436c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "# $Cardano Trading Analysis for 2025-02-10\n",
       "\n",
       "### **Current Price Analysis**\n",
       "- **Open:** 0.6815\n",
       "- **High:** 0.7177\n",
       "- **Low:** 0.6632\n",
       "- **Close:** 0.7037\n",
       "\n",
       "The price of $Cardano closed 3.59% higher than the previous day's close. This suggests a potential bullish reversal following a downward trend observed over the last few days. However, the volatility in the high-low range reflects uncertainty in the market.\n",
       "\n",
       "### **Trend Overview**\n",
       "- **Short-term:** \n",
       "  - The recent price action indicates a possible recovery as we see an upward close. The price is currently attempting to break resistance, but the last few days exhibited mixed movements (e.g., a decrease before the recent increase). \n",
       "- **Mid-term:**\n",
       "  - Over the past month, $Cardano has experienced significant volatility. While it reached its peak at around 1.079 earlier in January, the subsequent decline indicates selling pressure in the mid-term. A consolidation phase appears as buyers are trying to push the price back up.\n",
       "- **Long-term:**\n",
       "  - Over the past year, $Cardano has shown high volatility and a fluctuating price range, but it has generally been trending downwards since its recent highs. \n",
       "\n",
       "### **Trading Signals**\n",
       "- **Short-term Signal:** **Buy**\n",
       "  - The recent upward price movement along with a closing above 0.7000 indicates potential upward momentum. Short-term traders may consider buying into this recovery signal.\n",
       "\n",
       "- **Mid-term Signal:** **Hold**\n",
       "  - Within the last month, while recovery is in place, it is prudent to wait for confirmation of sustained upward movement before committing larger positions. A hold is advised to monitor the situation.\n",
       "\n",
       "- **Long-term Signal:** **Sell**\n",
       "  - Given that the longer-term trends show a downward trajectory since peaking at higher prices, long-term holders might consider selling or reducing positions, especially if the price fails to stay above recent resistance levels.\n",
       "\n",
       "### **Conclusion**\n",
       "Today’s price action indicates a bullish sentiment in the short term but still reflects uncertainty in the mid and long-term periods. It would be wise for traders to remain cautious and adjust positions as the market dynamics evolve further. Always consider your risk management strategies when deciding to enter or exit positions."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def get_response(prompt):\n",
    "    new_response = openai.chat.completions.create(model=\"gpt-4o-mini\",\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": f\"You are a trading analyst providing Buy/Sell/Hold signals based on ${base_data['name']} price history. Format your response in markdown.Note that today is {end_date.strftime('%Y-%m-%d')}\"},\n",
    "        {\"role\": \"user\", \"content\": prompt}\n",
    "    ],\n",
    "    stream=True,\n",
    "    max_tokens=5500\n",
    "    )\n",
    "    \n",
    "    # Initialize markdown cell output\n",
    "    markdown_content = \"\"\n",
    "    \n",
    "    # Stream response and accumulate markdown content\n",
    "    for chunk in new_response:\n",
    "        content = chunk.choices[0].delta.content or ''\n",
    "        markdown_content += content\n",
    "        \n",
    "        # Clear output and display updated markdown\n",
    "        display(Markdown(markdown_content), clear=True)\n",
    "        \n",
    "        yield content\n",
    "\n",
    "# Call the function and consume the generator to start streaming\n",
    "for _ in get_response(prompt):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f52bcc0a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
